/************************/
/*This File is not used */
/************************/

#include "nsPerseusMime.h"
#include "nsISupports.h"
#include "nsCRTGlue.h"
#include "nsMemory.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
/* Implementation file */

/**********************************************************
 *   PerseusInitDl Class Implementation 
 *
 *
 *
 * *********************************************************/
NS_IMPL_ISUPPORTS2(PerseusInitDl, nsIStreamListener, nsIRequestObserver)

PerseusInitDl::~PerseusInitDl()
{
  if (mByteData)
    nsMemory::Free(mByteData);
}



PerseusInitDl::PerseusInitDl(PRUint32 type)
: mByteData(nsnull),
  mType(type),
  mDoSilentDownload(PR_FALSE)
{
}

const PRInt32 defaultAllocLength = 2048;


NS_IMETHODIMP
PerseusInitDl::OnStartRequest(nsIRequest* request, nsISupports* context)
{
  LOG(("[PCC extension] - OnStartRequest "));

  nsresult rv;
  nsCOMPtr<nsIChannel> channel(do_QueryInterface(request,&rv));
  NS_ENSURE_SUCCESS(rv, rv);

  if (!channel)
    return NS_ERROR_FAILURE;

  // Get the URI //
  rv = channel->GetURI(getter_AddRefs(mURI));
  NS_ENSURE_SUCCESS(rv, rv);

  PRInt32 contentLength;
  rv = channel->GetContentLength(&contentLength);

  if (NS_FAILED(rv) || contentLength <= 0)
    contentLength = defaultAllocLength;

  mBufferOffset = 0;
  mBufferSize = 0;
  mByteData = (char*) nsMemory::Alloc(contentLength);
  if (!mByteData)
    return NS_ERROR_OUT_OF_MEMORY;

  mBufferSize = contentLength;
  return NS_OK;
}

NS_IMETHODIMP
PerseusInitDl::OnDataAvailable(nsIRequest* request,
                               nsISupports* context,
                               nsIInputStream *aIStream,
                               PRUint32 aSourceOffset,
                               PRUint32 aLength)
{

  LOG(("[PCC extension] - Downloading data"));


  if (!mByteData)
    return NS_ERROR_OUT_OF_MEMORY;

  PRUint32 amt;
  nsresult rv;
  //Do a check to see if we need to allocate more memory.
  if ((mBufferOffset + (PRInt32)aLength) > mBufferSize) {
      size_t newSize = (mBufferOffset + aLength) *2; // grow some more than needed
      char *newBuffer;
      newBuffer = (char*)nsMemory::Realloc(mByteData, newSize);
      if (!newBuffer) 
        return NS_ERROR_OUT_OF_MEMORY;

      mByteData = newBuffer;
      mBufferSize = newSize;
  }

  do {
      rv = aIStream->Read(mByteData+mBufferOffset,
                           aLength, &amt);
      NS_ENSURE_SUCCESS(rv, rv);

      if (amt == 0) 
        break;

      aLength -= amt;
      mBufferOffset += amt;

  } while (aLength > 0);

  return NS_OK;
}


NS_IMETHODIMP
PerseusInitDl::OnStopRequest(nsIRequest* request,
                             nsISupports* context,
                             nsresult aStatus)
{
  LOG(("[PCC extension] - End of download"));

  // nsNSSShutDownPreventionLock locker;
  //Check if the download succeeded - it might have failed due to
  //network issues, etc.
  if (NS_FAILED(aStatus)){
      //    handleContentDownloadError(aStatus);
      return aStatus;
  }

  LOG(("Downloaded :  %d Bytes",mBufferOffset));
  //Here we must read data downloaded and build the PCC
  //and register in the hash table 
  //
  //nsCOMPtr<nsIX509CertDB> certdb;
  //nsCOMPtr<nsICRLManager> crlManager;
return NS_OK;
  //nsresult rv;
  //nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
}




PRUint32
getMimeType(const char * aContentType)
{ 
  // Don't forget to update RegisterPCCListeners in nsPCCModule.cpp 
  // for every supported content type.

  if (!strcmp(aContentType, "Perseus-init"))
    return PerseusInitDl::CONV;
  return PerseusInitDl::UNKNOWN_TYPE;
}


/**********************************************************
 *   PCCListener Class Implementation 
 *
 *
 *
 * *********************************************************/



NS_IMPL_ISUPPORTS1(nsPerseusMime, nsIURIContentListener)

nsPerseusMime::nsPerseusMime()
{
  LOG(("[PCC extension] - nsPerseusMime register"));
}

nsPerseusMime::~nsPerseusMime()
{ 
  LOG(("[PCC extension] - nsPerseusMime unregister"));
}


nsresult
nsPerseusMime::init()
{
  return NS_OK;
}


/************** nsIURIContentListener implementation (see nsIURIContentListener.idl) */


NS_IMETHODIMP
nsPerseusMime::OnStartURIOpen(nsIURI *aURI, PRBool *aAbortOpen)
{
  //if we don't want to handle the URI, return PR_TRUE in
  //*aAbortOpen
  return PR_FALSE;//NS_OK;
}

NS_IMETHODIMP
nsPerseusMime::IsPreferred(const char * aContentType,
                           char ** aDesiredContentType,
                           PRBool * aCanHandleContent)
{
  return CanHandleContent(aContentType, PR_TRUE,
                          aDesiredContentType, aCanHandleContent);
}

NS_IMETHODIMP
nsPerseusMime::CanHandleContent(const char * aContentType,
                                PRBool aIsContentPreferred,
                                char ** aDesiredContentType,
                                PRBool * aCanHandleContent)
{
  PRUint32 type;
  type = getMimeType(aContentType);
  if (type == PerseusInitDl::UNKNOWN_TYPE) {
      *aCanHandleContent = PR_FALSE;
  } else {
      *aCanHandleContent = PR_TRUE;
  }
  return NS_OK;
}

NS_IMETHODIMP
nsPerseusMime::DoContent(const char * aContentType,
                         PRBool aIsContentPreferred,
                         nsIRequest * aRequest,
                         nsIStreamListener ** aContentHandler,
                         PRBool * aAbortProcess)
{
  PerseusInitDl *downLoader;
  PRUint32 type;
  type = getMimeType(aContentType);
  LOG(("[PCC extension] - Mime Type Detected"));
  if (type != PerseusInitDl::UNKNOWN_TYPE) {
      downLoader = new PerseusInitDl(type);
      if (downLoader) {
          downLoader->QueryInterface(NS_GET_IID(nsIStreamListener), 
                                     (void **)aContentHandler);
          return NS_OK;
      }
  }
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsPerseusMime::GetLoadCookie(nsISupports * *aLoadCookie)
{
  *aLoadCookie = mLoadCookie;
  NS_IF_ADDREF(*aLoadCookie);
  return NS_OK;
}

NS_IMETHODIMP
nsPerseusMime::SetLoadCookie(nsISupports * aLoadCookie)
{
  mLoadCookie = aLoadCookie;
  return NS_OK;
}

NS_IMETHODIMP
nsPerseusMime::GetParentContentListener(nsIURIContentListener ** aContentListener)
{
  *aContentListener = mParentContentListener;
  NS_IF_ADDREF(*aContentListener);
  return NS_OK;
}

NS_IMETHODIMP
nsPerseusMime::SetParentContentListener(nsIURIContentListener * aContentListener)
{
  mParentContentListener = aContentListener;
  return NS_OK;
}

